home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’95 / Grand Canyon Flythru / QD3D.c < prev    next >
Text File  |  1995-06-24  |  43KB  |  1,790 lines

  1. //*********************************************************************************
  2. //* QuickDraw 3D
  3. //*
  4. //* by Mark Sproul
  5. //* (C) 1995
  6. //*********************************************************************************
  7. //* Edit history
  8. //*********************************************************************************
  9. //*    Feb 27,    1995    Got QuickDraw 3D off of AppleLink
  10. //*    Mar  2,    1995    Got QD3D documentation off of AppleLink (6 Megs, 3 hrs to download)
  11. //*    Mar  4,    1995    Got QD3D rendering my data
  12. //*    Mar  5,    1995    Rendering DEM data
  13. //*    Mar  6,    1995    Able to render a full USGS-DEM data set (reduced to 75 by 75)
  14. //*    May 16,    1995    Starting a dialog with Apple about QD3D
  15. //*    May 17,    1995    Got 1.0 Beta of QD3D (new interfaces)
  16. //*    Jun    23,    1995    MacHack95, finnally got the shanding to work, enterd a movie in the contest
  17. //*********************************************************************************
  18.  
  19. //#define        _try_shader_
  20. #define            _ViewPlaneCamera_
  21. //#define        _USE_QD3D_LETTERS_
  22. //#define        _RENDER_TO_GWORLD_
  23.  
  24.  
  25. #include    <stdio.h>
  26. #include    <string.h>
  27. #include    <math.h>
  28.  
  29. #ifndef __MEMORY__
  30.     #include    <memory.h>
  31. #endif
  32.  
  33.  
  34. #include    <keyequates.h>
  35.  
  36.  
  37. #include    "UHsetup.h"
  38.  
  39. #ifdef SYMANTEC_C
  40.     #include    <math.h>
  41.     #include    <MixedMode.h>
  42.     #define    __CODEFRAGMENTS__
  43. //    #define        kUnresolvedSymbolAddress    kUnresolvedCFragSymbolAddress
  44.     #define        kUnresolvedSymbolAddress    1
  45.     #define    pi    (3.1415926535898)
  46.     
  47.     static    float sinf(float x) { return(x);};
  48.     static    float cosf(float x) { return(x);};
  49. #endif
  50.  
  51. #ifndef __CODEFRAGMENTS__
  52.     #include    <CodeFragments.h>
  53. #endif
  54.  
  55. //#define    ESCHER_VER_15    1
  56. #include    <QD3D.h>
  57. #include    <QD3DCamera.h>
  58. #include    <QD3DDrawContext.h>
  59. #include    <QD3DErrors.h>
  60. #include    <QD3DGroup.h>
  61. #include    <QD3DGeometry.h>
  62. #include    <QD3DIO.h>
  63. #include    <QD3DLight.h>
  64. #include    <QD3DMath.h>
  65. #include    <QD3DView.h>
  66. #include    <QD3DRenderer.h>
  67. #include    <QD3DSet.h>
  68. #include    <QD3DShader.h>
  69. #include    <QD3DStorage.h>
  70. #include    <vcInterface.h>
  71.  
  72. //*    MLS Library includes
  73. #include    "CtoPfunc.proto.h"
  74. #include    "dialog.support.proto.h"
  75. #include    "DrawUtilities.proto.h"
  76. #include    "ErrorString.h"
  77. #include    "FSSpecToPath.h"
  78. #include    "keyDownUtilities.proto.h"
  79. #include    "LogWindow.h"
  80. #include    "utilities.proto.h"
  81.  
  82.  
  83. #include    "Image32.h"
  84. #include    "info_Block.typedefs.h"
  85. #include    "info_Block.proto.h"
  86.  
  87. //#include    "Image32.menus.h"
  88. #include    "Image32.globals.h"
  89. //#include    "Image32.dialogs.h"
  90. #include    "Image32.proto.h"
  91. #include    "WindowStuff.proto.h"
  92. #include    "FileOpen.proto.h"
  93. #include    "FileSave.proto.h"
  94.  
  95. #include    "MOOV_proto.h"
  96. #include    "QD3D_IM32.h"
  97.  
  98.  
  99. TYPEwindowInfoPtr    qd3d_info;
  100.  
  101. Boolean            gQD3D_present            =    false;
  102. Boolean            gQD3D_viewer_present    =    false;
  103. Boolean            gQD3D_initialized        =    false;
  104. long            gRenderTotalTicks        =    0;
  105. long            gRenderTicks;
  106. TQ3Point3D        gCameraFrom                =    { 0.0, 0.0, 15.0 };
  107. TQ3Point3D        gCameraTo                =    { 0.0, 0.0, 0.0 };
  108. TQ3Vector3D        gCameraUp                =    { 0.0, 1.0, 0.0 };
  109.  
  110. long            *gSaveKeyMapSequence    =    nil;
  111. long            gSaveKeyMapIndex        =    0;
  112. #define            kSaveKeyMapMax            4096
  113.  
  114. #if 0
  115. TQ3ShaderObject        gShader                =    nil;
  116. #endif
  117.  
  118.  
  119. #ifdef _ViewPlaneCamera_
  120.     TQ3ViewPlaneCameraData            myViewCameraData;
  121. #else
  122.     TQ3ViewAngleAspectCameraData        myViewCameraData;
  123. #endif
  124.  
  125. TQ3GroupObject    GetTrigridData(Rect selectionRect, short scaleFactor);
  126.  
  127.  
  128. //*********************************************************************************
  129. static Boolean    QD3D_CheckIfPresent(void)
  130. {
  131. Boolean    qd3d_ok;
  132.  
  133.     if ((void *)Q3Initialize == (void *)kUnresolvedSymbolAddress)
  134.     {
  135.         qd3d_ok    =    false;
  136.     }
  137.     else
  138.     {
  139.         qd3d_ok    =    true;
  140.     }
  141.     return(qd3d_ok);
  142. }
  143.  
  144. //*********************************************************************************
  145. static Boolean    QD3D_CheckIfViewerPresent(void)
  146. {
  147. Boolean    qd3d_ok;
  148.  
  149.     if ((void *)Q3ViewerNew == (void *)kUnresolvedSymbolAddress)
  150.     {
  151.         qd3d_ok    =    false;
  152.     }
  153.     else
  154.     {
  155.         qd3d_ok    =    true;
  156.     }
  157.     return(qd3d_ok);
  158. }
  159.  
  160.  
  161. //*********************************************************************************
  162. Boolean    QD3D_Init(void)
  163. {
  164. TQ3Status        myStatus;
  165. TQ3Error        qd3dError;
  166. TQ3Error        getError;
  167. THz                appZone;
  168.  
  169.     gSaveKeyMapSequence        =    (long *)NewPtr(kSaveKeyMapMax * sizeof(long));
  170.  
  171.     gQD3D_initialized        =    false;
  172.  
  173.     gQD3D_present            =    QD3D_CheckIfPresent();
  174.     gQD3D_viewer_present    =    QD3D_CheckIfViewerPresent();
  175.     
  176.     
  177.     if (gQD3D_present)
  178.     {
  179.         myStatus    =    Q3Initialize();        //*    initialize QuickDraw3D
  180.         if (myStatus == kQ3Success)
  181.         {
  182.             gQD3D_initialized    =    true;
  183.         }
  184.         else
  185.         {
  186.             getError            =    Q3Error_Get(&qd3dError);
  187.             DisplayErrorCode(qd3dError);
  188.             gQD3D_initialized    =    false;
  189.         }
  190.     }
  191.     
  192.     if (sizeof(TQ3ViewObject) != sizeof(Ptr))    SysBeep(1);
  193.     if (sizeof(TQ3GroupObject) != sizeof(Ptr))    SysBeep(1);
  194.     if (sizeof(TQ3StyleObject) != sizeof(Ptr))    SysBeep(1);
  195.     
  196.     if (sizeof(TYPEwindowInfo) != gSizeOfInfoStructure)
  197.     {
  198.         SysBeep(1);
  199.         PutAlertMessage("\pSometing is VERY wrong with info structure");
  200.     }
  201.     
  202.     if (gQD3D_initialized)
  203.     {
  204.         //*    check to see if modern memory manager is enabled
  205.         appZone    =    ApplicZone();
  206.         if ((appZone->heapType & kNewStyleHeap) == 0)
  207.         {
  208.             //*    we ARE NOT running modern memory manger
  209.             PutAlertMessage("\pQD3D prefers to have Modern Memory Manger enabled");
  210.         }
  211.     }
  212.     
  213.     return(gQD3D_initialized);
  214. }
  215.  
  216.  
  217.  
  218. //*********************************************************************************
  219. void QD3D_ShutDown(void)
  220. {
  221. TYPEwindowInfoPtr    tinfo;
  222. TQ3Status            myStatus;
  223. short                ii, loopCnt;
  224. short                originalWindowCount;
  225.  
  226.     //*****************************************************************************
  227.     //*    it is VERY important that we close all QD3D windows, so go thru the list and 
  228.     //*    check for them
  229.     
  230.     originalWindowCount    =    gNumWindows;
  231.     ii                    =    0;
  232.     loopCnt                =    0;
  233.     while ((ii < gNumWindows) && (loopCnt < originalWindowCount))
  234.     {
  235.         tinfo    =    infoArray[ii];
  236.         if ((tinfo->wType == kWindType_3DMF_viewer) ||
  237.             (tinfo->pictureType == kPictureType_QD3Drendering))
  238.         {
  239.             DoCloseAWindow(tinfo);
  240.         }
  241.         else
  242.         {
  243.             ii++;
  244.         }
  245.         loopCnt++;
  246.     }
  247.     if (gQD3D_initialized)
  248.     {
  249.         myStatus    =    Q3Exit();        //*    unload QuickDraw3D
  250.     }
  251. }
  252.  
  253.  
  254. #ifdef _USE_QD3D_LETTERS_
  255. //*********************************************************************************
  256. static    TQ3GroupObject MyNewModel(void)
  257. {
  258. TQ3GroupObject            myModel;
  259. TQ3GeometryObject        myBox;
  260. TQ3BoxData                myBoxData;
  261. TQ3GroupPosition        myGroupPosition;
  262.     
  263. //*Data for boxes comprising Hello and World block letters.
  264. long            ii;
  265.  
  266. float            xorigin[34]    =    { -12, -9, -11, -7, -6, -6, -6, -2, -1, 3, 4,  
  267.                                     8, 9, 9, 11, -13, -12, -11, -9, -7, -6, -6, 
  268.                                  -4, -2, -1, -1,  1,  1,  3,  4,  8,  9,  9, 11};
  269.                                  
  270. float            yorigin[34]    =    { 0, 0, 3, 0, 6, 3, 0, 0, 0, 0, 0, 0, 6, 0, 0,
  271.                                  -8, -8, -7, -8, -8, -8, -2, -8, -8, -2, -5, -4,
  272.                                  -8, -8, -8, -8, -8, -2, -7};
  273.                                  
  274. float            height[34]     =    { 7, 7, 1, 7, 1, 1, 1, 7, 1, 7, 1, 7, 1, 1, 7,
  275.                                  7, 1, 3, 7, 7, 1, 1, 7, 7, 1, 1, 2, 3, 7, 1, 
  276.                                  7, 1, 1, 5};
  277.                                  
  278. float            width[34]      =    { 1, 1, 2, 1, 3, 2, 3, 1, 3, 1, 3, 1, 2, 2, 1,
  279.                                   1, 3, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 1, 3,
  280.                                  1, 2, 2, 1};
  281.  
  282. #define    kMaxPoints    34
  283.  
  284.     /*Create an ordered display group for the complete model.*/
  285.     myModel    =    Q3DisplayGroup_New();
  286.     if (myModel != nil)
  287.     {
  288.         /*Add all the boxes to the model.*/
  289.         myBoxData.faceAttributeSet    =    nil;
  290.         myBoxData.boxAttributeSet    =    0;
  291.         for (ii=0; ii<kMaxPoints; ii++)
  292.         {
  293.             Q3Point3D_Set(&myBoxData.origin, xorigin[ii], yorigin[ii], 1.0);
  294.             Q3Vector3D_Set(&myBoxData.orientation, 0, height[ii], 0);
  295.             Q3Vector3D_Set(&myBoxData.minorAxis, width[ii], 0, 0);
  296.             Q3Vector3D_Set(&myBoxData.majorAxis, 0, 0, 2);
  297.             myBox            =    Q3Box_New(&myBoxData);
  298.             myGroupPosition    =    Q3Group_AddObject(myModel, myBox);
  299.             Q3Object_Dispose(myBox);                    /*balance the reference count*/
  300.             if (myGroupPosition == nil)
  301.                 goto bail;
  302.         }
  303.     }
  304.     else
  305.     {
  306.         SysBeep(1);
  307.     }
  308.     return (myModel);                                    /*return the completed model*/
  309.  
  310. bail:
  311.     SysBeep(1);
  312.     /*If any of the above failed, then return an empty model.*/
  313.     return (nil);
  314.  
  315. }
  316. #endif
  317.  
  318. //*********************************************************************************
  319. static    TQ3DrawContextObject MyNewDrawContext(WindowPtr theWindow)
  320. {
  321. TQ3DrawContextObject                myDrawContext;
  322. TQ3DrawContextData                    myDrawContextData;
  323. TQ3MacDrawContextData                myMacDrawContextData;
  324. TQ3ColorARGB                        myClearColor    =    {0.0,  0.6, 0.9, 0.9};
  325.     
  326.     //*    Set the background color.
  327. //    Q3ColorRGB_Set(&myClearColor, .6, .9, .9);
  328. #if 1
  329.     //*    Fill in draw context data.
  330. //+    myDrawContextData.clearImageState    =    kQ3True;
  331.     myDrawContextData.clearImageMethod    =    kQ3ClearMethodWithColor;
  332.     myDrawContextData.clearImageColor    =    myClearColor;
  333.     myDrawContextData.paneState            =    kQ3False;
  334.     myDrawContextData.maskState            =    kQ3False;
  335.     myDrawContextData.doubleBufferState    =    kQ3True;
  336. //=    myDrawContextData.activeBuffer        =    EcBackBuffer;
  337. //+    myDrawContextData.activeBuffer        =    EcActiveBuffer_Back;
  338. #else
  339.     //*    Fill in draw context data.
  340.     myDrawContextData.clearImageState    =    kQ3True;
  341.     myDrawContextData.clearImageMethod    =    kQ3ClearMethodWithColor;
  342.     myDrawContextData.clearImageColor    =    myClearColor;
  343.     myDrawContextData.paneState            =    kQ3False;
  344.     myDrawContextData.maskState            =    kQ3False;
  345.     myDrawContextData.doubleBufferState    =    kQ3True;
  346. //=    myDrawContextData.activeBuffer        =    EcBackBuffer;
  347.     myDrawContextData.activeBuffer        =    EcActiveBuffer_Back;
  348. #endif
  349.     //*    Fill in Macintosh-specific draw context data.
  350.     myMacDrawContextData.drawContextData            =    myDrawContextData;
  351.     myMacDrawContextData.window                        =    (CWindowPtr) theWindow;
  352. //=    myMacDrawContextData.EtMacDrawContext2DLibrary    =    kQ3Mac2DLibraryNone;
  353.     myMacDrawContextData.library                    =    kQ3Mac2DLibraryNone;
  354.     myMacDrawContextData.viewPort                    =    nil;
  355.     myMacDrawContextData.grafPort                    =    nil;
  356.  
  357.     //*    Create draw context.
  358.     myDrawContext    =    Q3MacDrawContext_New(&myMacDrawContextData);
  359.     
  360.     return (myDrawContext);
  361. }
  362.  
  363.  
  364. //*********************************************************************************
  365. static    TQ3CameraObject MyNewCamera (void)
  366. {
  367. TQ3CameraObject                    myCamera;
  368. TQ3CameraData                    myCameraData;
  369. //TQ3ViewAngleAspectCameraData    myViewCameraData;
  370. //TQ3Point3D                    gCameraFrom    =    { 0.0, 0.0, 15.0 };
  371. //TQ3Point3D                    gCameraTo    =    { 0.0, 0.0, 0.0 };
  372. //TQ3Vector3D                    gCameraUp    =    { 0.0, 1.0, 0.0 };
  373.     
  374.     /*Fill in camera data.*/
  375. //=    myCameraData.placement.location                =    gCameraFrom;
  376.     myCameraData.placement.cameraLocation        =    gCameraFrom;
  377.     myCameraData.placement.pointOfInterest        =    gCameraTo;
  378.     myCameraData.placement.upVector                =    gCameraUp;
  379.     myCameraData.range.hither                    =    .1;
  380. //    myCameraData.range.yon                        =    15.0;
  381.     myCameraData.range.yon                        =    1000.0;
  382.     myCameraData.viewPort.origin.x                =    -1.0;
  383.     myCameraData.viewPort.origin.y                =    1.0;
  384.     myCameraData.viewPort.width                    =    2.0;
  385.     myCameraData.viewPort.height                =    2.0;
  386.  
  387. //=    myViewAngleCameraData.myViewAngleCameraData    =    myCameraData;
  388.     myViewCameraData.cameraData                    =    myCameraData;
  389. //+    myViewCameraData.fov                        =    100.0;
  390.  
  391. #ifdef _ViewPlaneCamera_
  392.     myViewCameraData.viewPlane                    =    15.0;
  393. //    myViewCameraData.halfWidthAtViewPlane        =    14.0;
  394.     myViewCameraData.halfHeightAtViewPlane        =    14.0;
  395.  
  396.     myViewCameraData.centerXOnViewPlane            =    0.0;
  397.     myViewCameraData.centerYOnViewPlane            =    0.0;
  398.  
  399.     myCamera    =    Q3ViewPlaneCamera_New(&myViewCameraData);
  400. #else
  401.     myViewCameraData.aspectRatioXToY            =    1;
  402.  
  403.     myCamera    =    Q3ViewAngleAspectCamera_New(&myViewCameraData);
  404. #endif
  405.     /*Return a camera.*/
  406.     return (myCamera);
  407. }
  408.  
  409.  
  410. //*********************************************************************************
  411. static    TQ3GroupObject MyNewLights (void)
  412. {
  413. TQ3GroupPosition                    myGroupPosition;
  414. TQ3GroupObject                        myLightList;
  415. TQ3LightData                        myLightData;
  416. TQ3PointLightData                    myPointLightData;
  417. TQ3DirectionalLightData                myDirLightData;
  418. TQ3LightObject                        myAmbientLight, myPointLight, myFillLight;
  419. TQ3Point3D                            pointLocation    =    { -10.0, 0.0, 10.0 };
  420. TQ3Vector3D                            fillDirection    =    { 10.0, 0.0, 10.0 };
  421. TQ3ColorRGB                            WhiteLight        =    { 1.0, 1.0, 1.0 };
  422.     
  423.     
  424.     /*Set up light data for ambient light.*/
  425.     myLightData.isOn        =    kQ3True;
  426.     myLightData.brightness    =    .2;
  427.     myLightData.color        =    WhiteLight;
  428.     
  429.     /*Create ambient light.*/
  430.     myAmbientLight    =    Q3AmbientLight_New(&myLightData);
  431.     if (myAmbientLight == nil)
  432.         goto bail;
  433.     
  434.     /*Create a point light.*/
  435.     myLightData.brightness            =    1.0;
  436.     myPointLightData.lightData        =    myLightData;
  437.     myPointLightData.castsShadows    =    kQ3False;
  438.     myPointLightData.attenuation    =    kQ3AttenuationTypeNone;
  439. //=    myPointLightData.location        =    &pointLocation;
  440.     myPointLightData.location        =    pointLocation;
  441.     myPointLight                    =    Q3PointLight_New(&myPointLightData);
  442.     if (myPointLight == nil)
  443.         goto bail;
  444.  
  445.     /*Create a directional light for fill.*/
  446.     myLightData.brightness        =    .2;
  447.     myDirLightData.lightData    =    myLightData;
  448.     myDirLightData.castsShadows    =    kQ3False;
  449. //?    myDirLightData.attenuation    =    kQ3AttenuationTypeNone;
  450. //=    myDirLightData.direction    =    &fillDirection;
  451.     myDirLightData.direction    =    fillDirection;
  452.     myFillLight                    =    Q3DirectionalLight_New(&myDirLightData);
  453.     if (myFillLight == nil)
  454.         goto bail;
  455.  
  456.     /*Create light group and add each of the lights to the group.*/
  457.     myLightList    =    Q3LightGroup_New();
  458.     if (myLightList == nil)
  459.         goto bail;
  460.         
  461.     myGroupPosition    =    Q3Group_AddObject(myLightList, myAmbientLight);
  462.     Q3Object_Dispose(myAmbientLight);                                                /*balance the reference count*/
  463.     if (myGroupPosition == 0)
  464.         goto bail;
  465.         
  466.     myGroupPosition    =    Q3Group_AddObject(myLightList, myPointLight);
  467.     Q3Object_Dispose(myPointLight);                                                /*balance the reference count*/
  468.     if (myGroupPosition == 0)
  469.         goto bail;
  470.         
  471.     myGroupPosition    =    Q3Group_AddObject(myLightList, myFillLight);
  472.     Q3Object_Dispose(myFillLight);                                                /*balance the reference count*/
  473.     if (myGroupPosition == 0)
  474.         goto bail;
  475.  
  476.     return (myLightList);
  477.     
  478. bail:
  479.     SysBeep(1);
  480. /*If any of the above failed, then return nothing!*/
  481.     return (nil);
  482. }
  483.  
  484.  
  485.  
  486.  
  487. //*********************************************************************************
  488. static    TQ3ViewObject MyNewView(WindowPtr theWindow)
  489. {
  490. TQ3Status                        myStatus;
  491. TQ3ViewObject                    myView;
  492. TQ3DrawContextObject            myDrawContext;
  493. TQ3RendererObject                myRenderer;
  494. TQ3CameraObject                    myCamera;
  495. TQ3GroupObject                    myLights;
  496.     
  497.     myView    =    Q3View_New();
  498.     
  499.     //*    Create and set draw context.
  500.     myDrawContext    =    MyNewDrawContext(theWindow);
  501.     if (myDrawContext == nil)
  502.         goto bail;
  503.         
  504.     myStatus    =    Q3View_SetDrawContext(myView, myDrawContext);
  505.     Q3Object_Dispose(myDrawContext);
  506.     if (myStatus == kQ3Failure)
  507.         goto bail;
  508.     
  509.     //*    Create and set renderer.
  510. #ifdef    _try_shader_
  511.     myRenderer    =    Q3Renderer_NewFromType(kQ3RendererTypeZBuffer);
  512. //    myRenderer    =    Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
  513. #else
  514.     if (OptionKeyDown())
  515.     {
  516.         myRenderer    =    Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
  517.     }
  518.     else if (ControlKeyDown())
  519.     {
  520.         myRenderer    =    Q3Renderer_NewFromType(kQ3RendererTypeGeneric);
  521.     }
  522.     else
  523.     {
  524.         myRenderer    =    Q3Renderer_NewFromType(kQ3RendererTypeWireFrame);
  525.     }
  526. #endif
  527.     if (myRenderer == nil)
  528.         goto bail;
  529.         
  530.     myStatus    =    Q3View_SetRenderer(myView, myRenderer);
  531.     Q3Object_Dispose(myRenderer);
  532.     if (myStatus == kQ3Failure)
  533.         goto bail;
  534.  
  535.     /*Create and set camera.*/
  536. #ifdef _ViewPlaneCamera_
  537.     myViewCameraData.halfWidthAtViewPlane        =    14.0;
  538. #else
  539.     myViewCameraData.fov    =    100.0;
  540. #endif
  541.     myCamera    =    MyNewCamera();
  542.     if (myCamera == nil)
  543.         goto bail;
  544.         
  545.     myStatus    =    Q3View_SetCamera(myView, myCamera);
  546.     Q3Object_Dispose(myCamera);
  547.     if (myStatus == kQ3Failure)
  548.         goto bail;
  549.  
  550.     /*Create and set lights.*/
  551.     myLights    =    MyNewLights();
  552.     if (myLights == nil)
  553.         goto bail;
  554.         
  555.     myStatus    =    Q3View_SetLightGroup(myView, myLights);
  556.     Q3Object_Dispose(myLights);
  557.     if (myStatus == kQ3Failure)
  558.         goto bail;
  559.  
  560.     return (myView);
  561.     
  562. bail:
  563.     SysBeep(1);
  564.     /*If any of the above failed, then don't return a view.*/
  565.     return (nil);
  566. }
  567.  
  568.  
  569.  
  570. //*********************************************************************************
  571. static void    QD3D_RenderToGWorld(TYPEwindowInfoPtr tinfo, Boolean doInvalRect)
  572. {
  573. //WindowInfoHandle                myWinfo;
  574. TQ3Status                        myStatus;
  575. TQ3DrawContextObject            myDrawContext;
  576. TQ3ViewStatus                    myViewStatus;
  577. long                            startTicks, endTicks;
  578. //CGrafPtr            port;
  579. //GDHandle            gdh;
  580. GrafPtr                savePort;
  581.  
  582.  
  583.     if ((tinfo == nil) || (tinfo->wptr == nil) || (tinfo->osGWorld == nil) || (tinfo->qd3D_view == nil))
  584.     {
  585.         return;
  586.     }
  587.     
  588. //    GetGWorld(&port, &gdh);
  589. //    SetGWorld(tinfo->osGWorld, nil);
  590.     GetPort(&savePort);
  591. #ifdef _RENDER_TO_GWORLD_
  592.     SetPort((GrafPtr)tinfo->osGWorld);
  593. #else
  594.     SetPort((GrafPtr)tinfo->wptr);
  595. #endif
  596.  
  597.     startTicks    =    TickCount();
  598.     
  599.     //myWinfo    =    (WindowInfoHandle) GetWRefCon(theWindow);
  600.     
  601.     //*    Start rendering.
  602.     myStatus    =    Q3View_StartRendering(tinfo->qd3D_view);
  603.     if (myStatus == kQ3Success)
  604.     {
  605.         myViewStatus    =    kQ3ViewStatusRetraverse;
  606.         while ((myStatus == kQ3Success) && (myViewStatus == kQ3ViewStatusRetraverse))
  607.         {
  608.     #if 0
  609.             if (gShader != nil)
  610.             {
  611.                 myStatus        =    Q3Style_Submit(gShader, tinfo->qd3D_view);
  612.                 if (myStatus == kQ3Failure)
  613.                     break;
  614.             }
  615.     #endif
  616.             if (tinfo->qd3D_interpolation != nil)
  617.             {
  618.                 myStatus        =    Q3Style_Submit(tinfo->qd3D_interpolation, tinfo->qd3D_view);
  619.                 if (myStatus == kQ3Failure)
  620.                     break;
  621.             }
  622.             if (tinfo->qd3D_backfacing != nil)
  623.             {
  624.                 myStatus        =    Q3Style_Submit(tinfo->qd3D_backfacing, tinfo->qd3D_view);
  625.                 if (myStatus == kQ3Failure)
  626.                     break;
  627.             }
  628.             if (tinfo->qd3D_fillstyle != nil)
  629.             {
  630.                 myStatus        =    Q3Style_Submit(tinfo->qd3D_fillstyle, tinfo->qd3D_view);
  631.                 if (myStatus == kQ3Failure)
  632.                     break;
  633.             }
  634.             if (tinfo->qd3D_model != nil)
  635.             {
  636.                 myStatus        =    Q3DisplayGroup_Submit(tinfo->qd3D_model, tinfo->qd3D_view);
  637.                 if (myStatus == kQ3Failure)
  638.                     break;
  639.             }
  640.             if (tinfo->qd3D_attributeSet != nil)
  641.             {
  642.                 myStatus    =    Q3AttributeSet_Submit(tinfo->qd3D_attributeSet, tinfo->qd3D_view);
  643.             }
  644.             
  645.             myViewStatus    =    Q3View_EndRendering(tinfo->qd3D_view);
  646.         }
  647.         //-    while (myViewStatus == kQ3ViewStatusReTraverse);
  648.         
  649.         //*    End rendering.
  650.         myStatus    =    Q3View_GetDrawContext(tinfo->qd3D_view, &myDrawContext);
  651.         if (myStatus == kQ3Success)
  652.         {
  653. //+            myStatus    =    ErDrawContext_UpdateFrontBuffer(myDrawContext);
  654.             Q3Object_Dispose(myDrawContext);
  655.         }
  656.     }
  657. //    SetGWorld(port, gdh);
  658.     SetPort(savePort);
  659.  
  660.     if (doInvalRect)
  661.     {
  662. //+        InvalWindowRect(tinfo);
  663.     }
  664.     endTicks            =    TickCount();
  665.     gRenderTicks        =    endTicks - startTicks;
  666.     gRenderTotalTicks    +=    gRenderTicks;
  667. }
  668.  
  669.  
  670.  
  671. //*********************************************************************************
  672. static void CreateQD3D_Window(void)
  673. {
  674. CGrafPtr            port;
  675. GDHandle            gdh;
  676. long                pixelsWide;
  677. long                pixelsTall;
  678. short                bitsDeep;
  679. Boolean                returnFlag;
  680. Rect                selectionRect;
  681. short                scaleFactor;
  682. short                scaleLimit;
  683.  
  684.     if (gQD3D_initialized == false)
  685.     {
  686.         PutAlertMessage("\pSorry, but QD3D is not available");
  687.         return;
  688.     }
  689.  
  690.  
  691.     GetGWorld(&port, &gdh);
  692.  
  693.     qd3d_info    =    info;
  694.     
  695.  
  696.     pixelsWide    =    600;
  697.     pixelsTall    =    400;
  698.     bitsDeep    =    8;
  699.     returnFlag    =    AllocateAndCreateNewGWorldWindow(    "\pQuick Draw 3D",
  700.                                                         pixelsWide,
  701.                                                         pixelsTall,
  702.                                                         bitsDeep,
  703.                                                         kPictureType_QD3Drendering,
  704.                                                         true);
  705.     if (returnFlag)
  706.     {
  707.         SetGWorld(info->osGWorld, nil);
  708.  
  709.         info->hasWorkToDo        =    true;
  710.         info->viewLocation.x    =    0.0;
  711.         info->viewLocation.y    =    0.0;
  712.         info->viewLocation.z    =    15.0;
  713.         info->viewBearing        =    0.0;
  714.         
  715.         gCameraFrom                =    info->viewLocation;
  716.         
  717.     #ifdef _RENDER_TO_GWORLD_
  718.         info->qd3D_view            =    MyNewView((GrafPtr)info->osGWorld);    //*Create a new view.
  719.     #else
  720.         info->qd3D_view            =    MyNewView((GrafPtr)info->wptr);    //*Create a new view.
  721.     #endif
  722.     
  723.         if (info->qd3D_view == nil)
  724.             goto bail;
  725.         
  726.         SetRect(&selectionRect, 0, 0, qd3d_info->pixelsPerLine, qd3d_info->nlines);
  727.         scaleLimit    =    75;
  728.         if (OptionKeyDown())
  729.         {
  730.             scaleLimit    =    50;
  731.         }
  732.         scaleFactor    =    1;
  733.         while (((qd3d_info->pixelsPerLine / scaleFactor) > scaleLimit) || ((qd3d_info->nlines / scaleFactor) > scaleLimit))
  734.         {
  735.             scaleFactor++;
  736.         }
  737.         info->imgDescript    =    (char *)NewPtr(64);
  738.         if (info->imgDescript != nil)
  739.         {
  740.             sprintf(info->imgDescript, "QuickDraw 3D Rendering, scale factor = %d", scaleFactor);
  741.         }
  742.         
  743.         //*    Create model to display.
  744.     #ifdef _USE_QD3D_LETTERS_
  745.         info->qd3D_model        =    MyNewModel();    /*see Listing 1-3 on page 1-19*/
  746.     #else
  747.         info->qd3D_model        =    GetTrigridData(selectionRect, scaleFactor);
  748.     #endif
  749.         if (info->qd3D_model == nil)
  750.             goto bail;
  751.         
  752.         //*    Configure the rendering styles.
  753.         info->qd3D_interpolation    =    Q3InterpolationStyle_New(kQ3InterpolationStyleNone);
  754.     
  755.         if (info->qd3D_interpolation == nil)
  756.             goto bail;
  757.             
  758.     //+    info->qd3D_backfacing    =    Q3BackfacingStyle_New(kQ3BackfacingStyleBoth);
  759.     //    info->qd3D_backfacing    =    Q3BackfacingStyle_New(kQ3BackfacingStyleRemove);
  760.         info->qd3D_backfacing    =    Q3BackfacingStyle_New(kQ3BackfacingStyleFlip);
  761.     
  762.         if (info->qd3D_backfacing == nil)
  763.             goto bail;
  764.             
  765.         info->qd3D_fillstyle    =    Q3FillStyle_New(kQ3FillStyleFilled);
  766.     //    info->qd3D_fillstyle    =    Q3FillStyle_New(kQ3FillStyleEdges);
  767.         if (info->qd3D_interpolation == nil)
  768.             goto bail;
  769.     
  770.     
  771.         QD3D_RenderToGWorld(info, true);
  772.     }
  773.     
  774.     
  775.     SetGWorld(port, gdh);
  776.     return;
  777.  
  778. bail:
  779.     SysBeep(1);
  780. //    /*If failed for any reason, then close the window.*/
  781. //    if (myWinfo != nil)
  782. //        DisposeHandle((Handle) myWinfo);
  783.  
  784.  
  785. //if (myWindow != nil)
  786. //        DisposeWindow(myWindow);
  787.     SetGWorld(port, gdh);
  788.     return;
  789. }
  790.  
  791.  
  792. //*********************************************************************************
  793. void    QD3D_DisposeObjects(TYPEwindowInfoPtr tinfo)
  794. {
  795. TQ3Status    qd3dStatus;
  796.  
  797.  
  798.     if ((tinfo == nil) || (tinfo->pictureType != kPictureType_QD3Drendering))
  799.     {
  800.         return;
  801.     }
  802.     if (tinfo->qd3D_fillstyle != nil)
  803.     {
  804.         qd3dStatus                    =    Q3Object_Dispose(tinfo->qd3D_fillstyle);
  805.         tinfo->qd3D_fillstyle        =    nil;
  806.     }
  807.     if (tinfo->qd3D_backfacing != nil)
  808.     {
  809.         qd3dStatus                    =    Q3Object_Dispose(tinfo->qd3D_backfacing);
  810.         tinfo->qd3D_backfacing        =    nil;
  811.     }
  812.     if (tinfo->qd3D_interpolation != nil)
  813.     {
  814.         qd3dStatus                    =    Q3Object_Dispose(tinfo->qd3D_interpolation);
  815.         tinfo->qd3D_interpolation    =    nil;
  816.     }
  817.     if (tinfo->qd3D_model != nil)
  818.     {
  819.         qd3dStatus                    =    Q3Object_Dispose(tinfo->qd3D_model);
  820.         tinfo->qd3D_model            =    nil;
  821.     }
  822.     if (tinfo->qd3D_view != nil)
  823.     {
  824.         qd3dStatus                    =    Q3Object_Dispose(tinfo->qd3D_view);
  825.         tinfo->qd3D_view            =    nil;
  826.     }
  827. }
  828.  
  829. //*********************************************************************************
  830. void    QD3D_DisposeViewer(TYPEwindowInfoPtr tinfo)
  831. {
  832.     if (tinfo->viewer_3DMF != nil)
  833.     {
  834.         Q3ViewerDispose(tinfo->viewer_3DMF);
  835.         tinfo->viewer_3DMF    =    nil;
  836.     }
  837. }
  838.  
  839. //*********************************************************************************
  840. void    QD3D_MenuCommand(void)
  841. {
  842.     CreateQD3D_Window();
  843.  
  844. }
  845.  
  846. //*********************************************************************************
  847. static    void    Recalc_FromAndTo(TYPEwindowInfoPtr tinfo, float deltaF, float deltaTheta)
  848. {
  849. #define    kVectorMagnitude    30.0
  850. //#define    kVectorIncrement    2.0
  851.  
  852. float    sinTheta;
  853. float    cosTheta;
  854. float    deltaX, deltaZ;
  855.  
  856.     if (deltaTheta != 0)
  857.     {
  858.         tinfo->viewBearing    +=    deltaTheta;
  859.     }
  860.     
  861.     sinTheta    =    sinf(tinfo->viewBearing);
  862.     cosTheta    =    cosf(tinfo->viewBearing);
  863.  
  864.     if (deltaF != 0)
  865.     {
  866.         deltaX                    =    deltaF * sinTheta;
  867.         deltaZ                    =    deltaF * cosTheta;
  868.         tinfo->viewLocation.x    +=    deltaX;
  869.         tinfo->viewLocation.z    -=    deltaZ;
  870.     }
  871.     
  872.     deltaX    =    kVectorMagnitude * sinTheta;
  873.     deltaZ    =    kVectorMagnitude * cosTheta;
  874.  
  875.     gCameraTo.x    =    tinfo->viewLocation.x + deltaX;
  876.     gCameraTo.z    =    tinfo->viewLocation.z - deltaZ;
  877.     
  878.     gCameraFrom    =    tinfo->viewLocation;
  879. }
  880.  
  881.  
  882. //*********************************************************************************
  883. Boolean    QD3D_DoKeyDownInWindow(TYPEwindowInfoPtr tinfo, char theChar, short keyModifiers)
  884. {
  885. Boolean            weHandledIt;
  886. #if 0
  887. TQ3Status        qd3dStatus;
  888. TQ3CameraObject    myCamera;
  889. float            deltaV;
  890. float            deltaTheta;
  891.  
  892.  
  893.     deltaV        =    2.0;
  894.     deltaTheta    =    pi/90;
  895.     
  896.     if (keyModifiers & optionKey)
  897.     {
  898.         deltaV        *=    3.0;
  899.         deltaTheta    *=    3.0;
  900.     }
  901.     weHandledIt        =    true;
  902.     switch(theChar)
  903.     {
  904.         case homeKey:
  905.             tinfo->viewLocation.x    =    0.0;
  906.             tinfo->viewLocation.y    =    0.0;
  907.             tinfo->viewLocation.z    =    15.0;
  908.             tinfo->viewBearing        =    0;
  909.             
  910.             gCameraTo.x                =    0;
  911.             gCameraTo.y                =    0;
  912.             gCameraTo.z                =    0;
  913.  
  914.             Recalc_FromAndTo(tinfo, 0.0, 0.0);
  915.             
  916.             gCameraUp.x                =    0.0;
  917.             gCameraUp.y                =    1.0;
  918.             gCameraUp.z                =    0.0;
  919. #ifndef _ViewPlaneCamera_
  920.             myViewCameraData.fov    =    100.0;
  921. #endif
  922.             break;
  923.             
  924.         case endKey:
  925.             tinfo->viewLocation.x    =    0.0;
  926.             tinfo->viewLocation.y    =    0.0;
  927.             tinfo->viewLocation.z    =    tinfo->qd3d_zDepthMax - 15.0;
  928.             tinfo->viewBearing        =    pi;
  929.             
  930.             gCameraTo.x                =    0;
  931.             gCameraTo.y                =    0;
  932.             gCameraTo.z                =    0;
  933.  
  934.             Recalc_FromAndTo(tinfo, 0.0, 0.0);
  935.             
  936.             gCameraUp.x                =    0.0;
  937.             gCameraUp.y                =    1.0;
  938.             gCameraUp.z                =    0.0;
  939. #ifndef _ViewPlaneCamera_
  940.             myViewCameraData.fov    =    100.0;
  941. #endif
  942.             break;
  943.             
  944.         case upArrowKey:
  945.             Recalc_FromAndTo(tinfo, deltaV, 0.0);
  946.             break;
  947.  
  948.         case downArrowKey:
  949.             Recalc_FromAndTo(tinfo, -deltaV, 0.0);
  950.             break;
  951.  
  952.         case leftArrowKey:
  953.             Recalc_FromAndTo(tinfo, 0.0, -deltaTheta);
  954.             break;
  955.  
  956.         case rightArrowKey:
  957.             Recalc_FromAndTo(tinfo, 0.0, deltaTheta);
  958.             break;
  959.  
  960.         case '8':
  961.             tinfo->viewLocation.y    +=    deltaV;
  962.             if (keyModifiers & shiftKey)
  963.             {
  964.                 gCameraTo.y    +=    deltaV;
  965.             }
  966.             break;
  967.  
  968.         case '2':
  969.             tinfo->viewLocation.y    -=    deltaV;
  970.             if (keyModifiers & shiftKey)
  971.             {
  972.                 gCameraTo.y    -=    deltaV;
  973.             }
  974.             break;
  975.     
  976.         case '4':
  977.             tinfo->viewLocation.x    -=    deltaV;
  978.             if (keyModifiers & shiftKey)
  979.             {
  980.                 gCameraTo.x    -=    deltaV;
  981.             }
  982.             break;
  983.     
  984.         case '6':
  985.             tinfo->viewLocation.x    +=    deltaV;
  986.             if (keyModifiers & shiftKey)
  987.             {
  988.                 gCameraTo.x    +=    deltaV;
  989.             }
  990.             break;
  991.  
  992.         case '7':
  993.             gCameraTo.x    -=    deltaV;
  994.             break;
  995.  
  996.         case '9':
  997.             gCameraTo.x    +=    deltaV;
  998.             break;
  999.  
  1000.         case pageUpKey:
  1001.             tinfo->viewLocation.y    +=    deltaV;
  1002.             if (keyModifiers & shiftKey)
  1003.             {
  1004.                 gCameraTo.y    +=    deltaV;
  1005.             }
  1006.             break;
  1007.     
  1008.         case pageDnKey:
  1009.             tinfo->viewLocation.y    -=    deltaV;
  1010.             if (keyModifiers & shiftKey)
  1011.             {
  1012.                 gCameraTo.y    -=    deltaV;
  1013.             }
  1014.             break;
  1015.  
  1016.         case 0x20:
  1017.             if (tinfo->movieBeingSaved)
  1018.             {
  1019.                 WriteFrameToMOOVieFile(tinfo, gMovieRefNum);
  1020.                 SysBeep(1);
  1021.             }
  1022.             break;
  1023.  
  1024.         default:
  1025.             weHandledIt        =    false;
  1026.             break;
  1027.     }
  1028.     gCameraFrom    =    tinfo->viewLocation;
  1029.  
  1030.     //*    Create and set camera.
  1031.     myCamera    =    MyNewCamera();
  1032.     if (myCamera != nil)
  1033.     {
  1034.         qd3dStatus    =    Q3View_SetCamera(info->qd3D_view, myCamera);
  1035.         Q3Object_Dispose(myCamera);
  1036.  
  1037.         QD3D_RenderToGWorld(tinfo, false);
  1038.         
  1039.     #ifdef _RENDER_TO_GWORLD_
  1040.         UpdateWindowFromGWorld(tinfo, kUpdate_fast);
  1041.     #endif
  1042.     }
  1043.     else
  1044.     {
  1045.         SysBeep(1);
  1046.     }
  1047. #else
  1048.     weHandledIt    =    true;
  1049. #endif
  1050.     return(weHandledIt);
  1051. }
  1052.  
  1053.  
  1054. //*********************************************************************************
  1055. static void    ProcessQD3D_KeyMAP(TYPEwindowInfoPtr tinfo, KeyMap keyMap)
  1056. {
  1057. Boolean            needToRender;
  1058. Boolean            shiftKeyWasDown        =    false;
  1059. Boolean            capsLockyWasDown    =    false;
  1060. float            deltaV;
  1061. float            deltaTheta;
  1062. TQ3CameraObject    myCamera;
  1063. TQ3Status        qd3dStatus;
  1064.  
  1065.  
  1066.     deltaV        =    0.75;
  1067.     deltaTheta    =    pi/120;
  1068.  
  1069.     needToRender    =    false;
  1070.     
  1071.     
  1072.     if (keyMap[1] & 0x000004)        //*    option key
  1073.     {
  1074.         deltaV        *=    3.0;
  1075.         deltaTheta    *=    3.0;
  1076.     }
  1077.     if (keyMap[1] & 0x000001)        //*    shift key
  1078.     {
  1079.         shiftKeyWasDown    =    true;
  1080.     }
  1081.     
  1082.     if (keyMap[1] & 0x000002)        //*    caps lock key
  1083.     {
  1084.         capsLockyWasDown    =    true;
  1085.     }
  1086.     
  1087.     if (keyMap[3] & 0x000040)        //*    up arrow
  1088.     {
  1089.         Recalc_FromAndTo(tinfo, deltaV, 0.0);
  1090.         needToRender    =    true;
  1091.     }
  1092.     if (keyMap[3] & 0x000020)        //*    down arrow
  1093.     {
  1094.         Recalc_FromAndTo(tinfo, -deltaV, 0.0);
  1095.         needToRender    =    true;
  1096.     }
  1097.     if (keyMap[3] & 0x000008)        //*    left arrow
  1098.     {
  1099.         Recalc_FromAndTo(tinfo, 0.0, -deltaTheta);
  1100.         needToRender    =    true;
  1101.     }
  1102.     if (keyMap[3] & 0x000010)        //*    right arrow
  1103.     {
  1104.         Recalc_FromAndTo(tinfo, 0.0, deltaTheta);
  1105.         needToRender    =    true;
  1106.     }
  1107.     if (keyMap[3] & 0x000800)        //*    home key
  1108.     {
  1109.         tinfo->viewLocation.x    =    0.0;
  1110.         tinfo->viewLocation.y    =    0.0;
  1111.         tinfo->viewLocation.z    =    15.0;
  1112.         tinfo->viewBearing        =    0;
  1113.         
  1114.         gCameraTo.x                =    0;
  1115.         gCameraTo.y                =    0;
  1116.         gCameraTo.z                =    0;
  1117.  
  1118.         Recalc_FromAndTo(tinfo, 0.0, 0.0);
  1119.         
  1120.         gCameraUp.x                =    0.0;
  1121.         gCameraUp.y                =    1.0;
  1122.         gCameraUp.z                =    0.0;
  1123.     #ifndef _ViewPlaneCamera_
  1124.         myViewCameraData.fov    =    100.0;
  1125.     #endif
  1126.         needToRender    =    true;
  1127.     }
  1128.     
  1129.     if (keyMap[3] & 0x008000)        //*    end key
  1130.     {
  1131.  
  1132.         tinfo->viewLocation.x    =    0.0;
  1133.         tinfo->viewLocation.y    =    0.0;
  1134.         tinfo->viewLocation.z    =    tinfo->qd3d_zDepthMax - 15.0;
  1135.         tinfo->viewBearing        =    pi;
  1136.         
  1137.         gCameraTo.x                =    0;
  1138.         gCameraTo.y                =    0;
  1139.         gCameraTo.z                =    0;
  1140.     
  1141.         Recalc_FromAndTo(tinfo, 0.0, 0.0);
  1142.         
  1143.         gCameraUp.x                =    0.0;
  1144.         gCameraUp.y                =    1.0;
  1145.         gCameraUp.z                =    0.0;
  1146.     #ifndef _ViewPlaneCamera_
  1147.         myViewCameraData.fov    =    100.0;
  1148.     #endif
  1149.         needToRender    =    true;
  1150.     }
  1151.     
  1152.     if (keyMap[2] & 0x000008)        //*    '8' key
  1153.     {
  1154.         tinfo->viewLocation.y    +=    deltaV;
  1155.         if (shiftKeyWasDown)
  1156.         {
  1157.             gCameraTo.y    +=    deltaV;
  1158.         }
  1159.         needToRender    =    true;
  1160.     }
  1161.     if (keyMap[2] & 0x001000)    //*    '2' key
  1162.     {
  1163.         tinfo->viewLocation.y    -=    deltaV;
  1164.         if (shiftKeyWasDown)
  1165.         {
  1166.             gCameraTo.y    -=    deltaV;
  1167.         }
  1168.         needToRender    =    true;
  1169.     }
  1170.  
  1171.     if (needToRender)
  1172.     {
  1173.         gCameraFrom    =    tinfo->viewLocation;
  1174.     
  1175.         //*    Create and set camera.
  1176.         myCamera    =    MyNewCamera();
  1177.         if (myCamera != nil)
  1178.         {
  1179.             qd3dStatus    =    Q3View_SetCamera(info->qd3D_view, myCamera);
  1180.             Q3Object_Dispose(myCamera);
  1181.     
  1182.             QD3D_RenderToGWorld(tinfo, false);
  1183.             
  1184.         #ifdef _RENDER_TO_GWORLD_
  1185.             UpdateWindowFromGWorld(tinfo, kUpdate_fast);
  1186.         #endif
  1187.         }
  1188.     //    if (tinfo->movieBeingSaved && capsLockyWasDown)
  1189.         if (tinfo->movieBeingSaved)
  1190.         {
  1191.             WriteFrameToMOOVieFile(tinfo, gMovieRefNum);
  1192.         }
  1193.     }
  1194.     else if (keyMap[0] || keyMap[1] || keyMap[2] || keyMap[3])
  1195.     {
  1196.         needToRender    =    false;
  1197.     }
  1198. }
  1199.  
  1200.  
  1201.  
  1202. //*********************************************************************************
  1203. static void    DoAllKeyStrokes(TYPEwindowInfoPtr tinfo)
  1204. {
  1205. KeyMap        keyMap;
  1206. long        ii;
  1207.  
  1208.     ii    =    0;
  1209.     while (ii<gSaveKeyMapIndex)
  1210.     {
  1211.         keyMap[0]    =    gSaveKeyMapSequence[ii++];
  1212.         keyMap[1]    =    gSaveKeyMapSequence[ii++];
  1213.         keyMap[2]    =    gSaveKeyMapSequence[ii++];
  1214.         keyMap[3]    =    gSaveKeyMapSequence[ii++];
  1215.     
  1216.         ProcessQD3D_KeyMAP(tinfo, keyMap);
  1217.         
  1218.         if (CommandPeriod())
  1219.         {
  1220.             break;
  1221.         }
  1222.     }
  1223. }
  1224.  
  1225.  
  1226. //*********************************************************************************
  1227. void    DoBackground_QD3D(TYPEwindowInfoPtr tinfo)
  1228. {
  1229. KeyMap            keyMap;
  1230. Boolean            processKey;
  1231.  
  1232.     GetKeys(keyMap);
  1233.     processKey    =    true;
  1234.     
  1235.     if (gSaveKeyMapSequence != nil)
  1236.     {
  1237.         if (keyMap[1] & 0x000800)        //*    back space key
  1238.         {
  1239.             gSaveKeyMapIndex--;
  1240.             if (gSaveKeyMapIndex < 0)
  1241.             {
  1242.                 gSaveKeyMapIndex    =    0;
  1243.             }
  1244.         }
  1245.         else if (keyMap[1] & 0x002000)    //*    escape
  1246.         {
  1247.             SysBeep(1);
  1248.             gSaveKeyMapIndex    =    0;
  1249.         }
  1250.         else if (keyMap[3] & 0x004)        //*    f1 key
  1251.         {
  1252.             SysBeep(1);
  1253.             SysBeep(1);
  1254.             DoAllKeyStrokes(tinfo);
  1255.         }
  1256.         else
  1257.         {
  1258.             if (gSaveKeyMapIndex < kSaveKeyMapMax)
  1259.             {
  1260.                 gSaveKeyMapSequence[gSaveKeyMapIndex++]    =    keyMap[0];
  1261.                 gSaveKeyMapSequence[gSaveKeyMapIndex++]    =    keyMap[1];
  1262.                 gSaveKeyMapSequence[gSaveKeyMapIndex++]    =    keyMap[2];
  1263.                 gSaveKeyMapSequence[gSaveKeyMapIndex++]    =    keyMap[3];
  1264.             }
  1265.             else
  1266.             {
  1267.                 SysBeep(1);
  1268.                 SysBeep(1);
  1269.                 SysBeep(1);
  1270.             }
  1271.         }
  1272.     }
  1273.     
  1274.     if (processKey)
  1275.     {
  1276.         ProcessQD3D_KeyMAP(tinfo, keyMap);
  1277.     }
  1278. }
  1279.  
  1280.  
  1281. #ifdef    _try_shader_
  1282. //*********************************************************************************
  1283. static    TQ3AttributeSet GetPixmapTextureAttributeSet(EtPixmap myPixmap)
  1284. {
  1285. EtShaderObject                    myShader;
  1286. TQ3AttributeSet                    myAttrSet;
  1287. EtTextureObject                    myTexture;
  1288. TQ3Status                        myResult;
  1289.  
  1290.  
  1291.     //*    create a new texture from the pixmap passed in
  1292.     myTexture    =    ErPixmapTexture_New(&myPixmap);
  1293.     if (myTexture == NULL)
  1294.         return (nil);
  1295.  
  1296.     //*    create a new texture shader from the texture
  1297.     myShader    =    ErTextureShader_New(myTexture);
  1298.     if (myShader == NULL)
  1299.         return (nil);
  1300.  
  1301.     /*create a new empty attribute set*/
  1302.     myAttrSet    =    ErAttributeSet_New();
  1303.     if (myAttrSet == NULL)
  1304.         return (nil);
  1305.  
  1306.     /*add the texture shader to the attribute set*/
  1307.     myResult    =    ErAttributeSet_Add(myAttrSet, EcAttributeType_SurfaceShader, (void *)myShader);
  1308.  
  1309.     if (myResult == kQ3Failure)
  1310.         return (nil);
  1311.  
  1312.  
  1313.  
  1314.     return(myAttrSet);
  1315. }
  1316. #endif
  1317.  
  1318.  
  1319. #ifndef    _USE_QD3D_LETTERS_
  1320. //*********************************************************************************
  1321. static    TQ3GroupObject    GetTrigridData(Rect selectionRect, short scaleFactor)
  1322. {
  1323. TYPEwindowInfoPtr    tinfo;
  1324. PixMapHandle        myOsPixMapHandle;            //*    offscreen pixel map
  1325. Ptr                    scrnPtr;
  1326. Ptr                    rowPtr;
  1327. long                sBytesPerRow;
  1328. long                ii, jj;
  1329. short                pixelsWide, pixelsTall;
  1330. short                pixelValue;
  1331. TQ3GroupObject        myGroup;
  1332. TQ3TriGridData        myTriGridData;
  1333. TQ3Vertex3D            *myVertices;
  1334. //TQ3AttributeSet        *myFaceAtributes;
  1335. //unsigned long        rowIndex, columnIndex;
  1336. TQ3Point3D            position;
  1337. //TQ3Status            myStatus;
  1338. TQ3GroupPosition    myGroupPosition;
  1339. TQ3GeometryObject    myTriGridDataObject;
  1340. TQ3Param2D            param2D;
  1341. long                myVertIndex;
  1342. long                max_VertIndex;
  1343. short                minPixValue, maxPixValue;
  1344. float                pixelRange;
  1345. float                pixelFloat;
  1346. long                iiScaled;
  1347. long                jjScaled;
  1348. short                image_nlines;
  1349. short                image_pixelsPerLine;
  1350. #ifdef    _try_shader_
  1351. //    TQ3Status            myResult;
  1352. //    EtShaderObject        myShader;
  1353.     TQ3AttributeSet        myAttributeSet;
  1354.     TQ3Pixmap            myPixmap;
  1355. //    TQ3Status            qd3dStatus;
  1356. #endif
  1357. TQ3ShaderObject            myIlluminationShader;
  1358.  
  1359.  
  1360.     tinfo    =    qd3d_info;
  1361.     
  1362.     if (tinfo == nil)
  1363.     {
  1364.         return(nil);
  1365.     }
  1366.     if (tinfo->pixelDepth != 8)
  1367.     {
  1368.         return(nil);
  1369.     }
  1370.     
  1371.     //**********************************************************************
  1372.     myOsPixMapHandle    =    GetGWorldPixMap(tinfo->osGWorld);
  1373.     LockPixels(myOsPixMapHandle);
  1374.     scrnPtr                =    GetPixBaseAddr(myOsPixMapHandle);
  1375.     sBytesPerRow        =    (*myOsPixMapHandle)->rowBytes & 0x3fff;
  1376.     rowPtr                =    scrnPtr;
  1377.     //**********************************************************************
  1378.  
  1379.  
  1380.  
  1381.     pixelsWide            =    tinfo->pixelsPerLine / scaleFactor;
  1382.     pixelsTall            =    tinfo->nlines / scaleFactor;
  1383.  
  1384.     //**********************************************************************
  1385.     //*    This is sortof weird,
  1386.     //*    we need the Horz and Vert to be even
  1387.  
  1388.     if ((pixelsWide % 2) != 0)
  1389.     {
  1390.         pixelsWide    -=    1;
  1391.     }
  1392.     if ((pixelsTall % 2) != 0)
  1393.     {
  1394.         pixelsTall    -=    1;
  1395.     }
  1396.     image_nlines        =    scaleFactor * pixelsTall;
  1397.     image_pixelsPerLine    =    scaleFactor * pixelsWide;
  1398.     
  1399.     //*    add 2 to the height for a front step and a back step
  1400.     pixelsTall            +=    2;
  1401.  
  1402.     
  1403.     max_VertIndex        =    pixelsWide * pixelsTall;
  1404.     myVertices            =    (TQ3Vertex3D *)NewPtrClear(max_VertIndex * sizeof(TQ3Vertex3D));
  1405. //    myFaceAtributes        =    (TQ3AttributeSet *)NewPtrClear(pixelsWide * pixelsTall * sizeof(TQ3AttributeSet));
  1406.     myTriGridData.triGridAttributeSet    =    0;
  1407.  
  1408. #ifdef    _try_shader_
  1409.     myPixmap.image        =    GetPixBaseAddr(myOsPixMapHandle);
  1410.     myPixmap.width        =    tinfo->pixelsPerLine;
  1411.     myPixmap.height        =    tinfo->nlines;
  1412.     myPixmap.rowBytes    =    (*myOsPixMapHandle)->rowBytes & 0x3fff;
  1413.     myPixmap.pixelSize    =    8;
  1414.     myPixmap.pixelType    =    EcPixelType_RGB8;
  1415.     myPixmap.bitOrder    =    EcEndian_Big;
  1416.     myPixmap.byteOrder    =    EcEndian_Big;
  1417.     myAttributeSet        =    GetPixmapTextureAttributeSet(myPixmap);
  1418.  
  1419.  
  1420. //    myAttributeSet        =    ErAttributeSet_New();
  1421. //    myShader            =    Q3PhongIllumination_New();
  1422.     if (myAttributeSet != nil)
  1423.     {
  1424.         myTriGridData.triGridAttributeSet    =    myAttributeSet;
  1425.     }
  1426. #endif
  1427.  
  1428. //    myTriGridData.numUVertices            =    pixelsWide;
  1429. //    myTriGridData.numVVertices            =    pixelsTall;
  1430.  
  1431.     myTriGridData.numRows                =    pixelsWide;
  1432.     myTriGridData.numColumns            =    pixelsTall;
  1433.  
  1434.     myTriGridData.vertices                =    myVertices;
  1435.     myTriGridData.facetAttributeSet        =    nil;
  1436.     
  1437.     
  1438.  
  1439.     //**********************************************************************
  1440.     //*    first go thru and find the min and max pixel value
  1441.     minPixValue            =    255;
  1442.     maxPixValue            =    0;
  1443.     
  1444.     for (ii=0; ii<tinfo->nlines; ii +=scaleFactor)
  1445.     {
  1446.         for (jj=0; jj<tinfo->pixelsPerLine; jj +=scaleFactor)
  1447.         {
  1448.             pixelValue    =    rowPtr[jj] & 0x00ff;
  1449.             if (pixelValue < minPixValue)
  1450.             {
  1451.                 minPixValue    =    pixelValue;
  1452.             }
  1453.             if (pixelValue > maxPixValue)
  1454.             {
  1455.                 maxPixValue    =    pixelValue;
  1456.             }
  1457.         }
  1458.         rowPtr    +=    sBytesPerRow * scaleFactor;
  1459.     }
  1460.     pixelRange    =    maxPixValue - minPixValue;
  1461.     
  1462.     //**********************************************************************
  1463.     //*    now go thru the image again and figure out the values
  1464.     myVertIndex                =    0;
  1465.  
  1466.     info->qd3d_zDepthMax    =    0.0;    //*    this DOES go to info, NOT tinfo
  1467.  
  1468.     //*    the U/V space is rotated 90 degrees from what we are used to,
  1469.     //*    we are going to start at the bottom, and move up and then right
  1470.     //*    to fill in the vertice values
  1471.  
  1472. //?    rowPtr            =    scrnPtr + ((tinfo->nlines - 1) * sBytesPerRow);
  1473.  
  1474.     
  1475.     rowPtr            =    scrnPtr + ((tinfo->nlines - 1) * sBytesPerRow);
  1476.  
  1477.  
  1478.  
  1479.     for (jj=0; jj<image_pixelsPerLine; jj +=scaleFactor)
  1480.     {
  1481.         //*    this is so the front is very low
  1482.         if (myVertIndex < max_VertIndex)
  1483.         {
  1484.             jjScaled    =    jj / scaleFactor;
  1485.             position.x    =    (1.0 * jjScaled) - (pixelsTall / 2.0);
  1486.             position.z    =    0;
  1487.  
  1488.             position.y    =    -16.0;
  1489.  
  1490.             myVertices[myVertIndex].point    =    position;
  1491.             myVertIndex++;
  1492.         }
  1493.  
  1494.         rowPtr            =    scrnPtr + ((tinfo->nlines - 1) * sBytesPerRow);
  1495.  
  1496.         for (ii=0; ii<image_nlines; ii +=scaleFactor)
  1497.         {
  1498.             pixelValue    =    rowPtr[jj] & 0x00ff;
  1499.  
  1500.             iiScaled    =    ii / scaleFactor;
  1501.             jjScaled    =    jj / scaleFactor;
  1502.  
  1503.             pixelFloat    =    pixelValue - minPixValue;
  1504.             
  1505.             position.x    =    (1.0 * jjScaled) - (pixelsTall / 2.0);
  1506.             position.z    =    -1.0 * iiScaled;
  1507.             if (position.z < info->qd3d_zDepthMax)    //*    this DOES go to info, NOT tinfo
  1508.             {
  1509.                 info->qd3d_zDepthMax    =    position.z;    //*    this DOES go to info, NOT tinfo
  1510.             }
  1511.  
  1512.             position.y    =    (pixelFloat / pixelRange) * 30.0;
  1513.             position.y    -=    15.0;
  1514.  
  1515.  
  1516.             if (myVertIndex < max_VertIndex)
  1517.             {
  1518.                 myVertices[myVertIndex].point    =    position;
  1519.             #if 1
  1520.                 param2D.u =        (myVertIndex % image_nlines) / ((float)  image_pixelsPerLine);
  1521.                 param2D.v = 1.0 - ((myVertIndex / image_nlines) / ((float) (image_nlines - 1.0)));
  1522.  
  1523.                 myVertices[myVertIndex].attributeSet    =    Q3AttributeSet_New();
  1524.                 Q3AttributeSet_Add(myVertices[myVertIndex].attributeSet, kQ3AttributeTypeShadingUV, ¶m2D);
  1525.             #endif
  1526.  
  1527.                 myVertIndex++;
  1528.             }
  1529.             rowPtr            -=    sBytesPerRow * scaleFactor;
  1530.         }
  1531.         //*    this is so the back is very low
  1532.         if (myVertIndex < max_VertIndex)
  1533.         {
  1534.             iiScaled    =    ii / scaleFactor;
  1535.             jjScaled    =    jj / scaleFactor;
  1536.             position.x    =    (1.0 * jjScaled) - (pixelsTall / 2.0);
  1537.             position.z    =    -1.0 * iiScaled;
  1538.  
  1539.             position.y    =    -16.0;
  1540.  
  1541.             myVertices[myVertIndex].point    =    position;
  1542.             myVertIndex++;
  1543.         }
  1544.     }
  1545.  
  1546.     UnlockPixels(myOsPixMapHandle);
  1547.  
  1548.     //******************************
  1549.     //    code from  MyNewModel
  1550.  
  1551. //    myGroup                =    Q3OrderedDisplayGroup_New();
  1552.     myGroup                =    Q3DisplayGroup_New();
  1553.  
  1554.     myTriGridDataObject    =    Q3TriGrid_New(&myTriGridData);
  1555.  
  1556.  
  1557.     if ((myGroup != nil) && (myTriGridDataObject != nil))
  1558.     {
  1559.     #if 1
  1560.         myIlluminationShader    =    Q3PhongIllumination_New();
  1561.         if (myIlluminationShader) 
  1562.         {
  1563.             Q3Group_AddObject(myGroup, myIlluminationShader);
  1564.             Q3Object_Dispose(myIlluminationShader);    
  1565.         }
  1566.     #endif
  1567.         myGroupPosition    =    Q3Group_AddObject(myGroup, myTriGridDataObject);
  1568.         Q3Object_Dispose(myTriGridDataObject);            /*balance the reference count*/
  1569.     }
  1570.     else
  1571.     {
  1572.         SysBeep(1);
  1573.     }
  1574.     return (myGroup);                                    /*return the completed model*/
  1575. }
  1576. #endif
  1577.  
  1578.  
  1579.  
  1580. //*************************************************************************
  1581. Boolean OpenFile_3DMF(FSSpec *fsSpec)
  1582. {
  1583. long                pixelsWide;
  1584. long                pixelsTall;
  1585. short                bitsDeep;
  1586. //ViewerObject        viewer;
  1587. short                fRefNum;
  1588. OSErr                iErr;
  1589. Boolean                returnFlag;
  1590. long                longRefNum;
  1591. unsigned long        viewerFlags;
  1592.  
  1593.  
  1594.     if (gQD3D_viewer_present == false)
  1595.     {
  1596.         PutAlertMessage("\pSorry, but QD3D viewer is not available");
  1597.         return(false);
  1598.     }
  1599.  
  1600.     pixelsWide    =    600;
  1601.     pixelsTall    =    400;
  1602.     bitsDeep    =    8;
  1603.  
  1604.     returnFlag    =    AllocateAndCreateNewWindow(    fsSpec->name,
  1605.                                                 pixelsWide,
  1606.                                                 pixelsTall,
  1607.                                                 bitsDeep,
  1608.                                                 kWindType_3DMF_viewer,
  1609.                                                 kPictureType_3DMF,
  1610.                                                 gShowWindowOnOpenFlag);
  1611.     if (returnFlag)
  1612.     {
  1613.         viewerFlags    =    vcDefault;
  1614.         viewerFlags    |=    vcDrawFrame;
  1615.         viewerFlags    |=    vcDraggingOff;
  1616.         viewerFlags    |=    vcButtonTruck;
  1617.     //    viewerFlags    |=    vcButtonZoom;
  1618.     //    viewerFlags    |=    vcButtonDolly;
  1619.         
  1620.         
  1621.         // create a viewer object
  1622.     //    viewer    =    Q3ViewerNew((CGrafPtr)info->wptr, &(info->wptr->portRect), vcDefault);
  1623.         info->viewer_3DMF    =    Q3ViewerNew((CGrafPtr)info->wptr, &(info->wptr->portRect), viewerFlags);
  1624.  
  1625.         // Open the file and get back a "fRefNum"
  1626.         iErr    =    FSpOpenDF(fsSpec, fsRdPerm, &fRefNum);
  1627.         if (iErr == noErr)
  1628.         {
  1629.             // Pass the fRefNum to viewer to read
  1630.             longRefNum    =    fRefNum;
  1631.             Q3ViewerUseFile(info->viewer_3DMF, longRefNum);
  1632.  
  1633.             iErr    =    FSClose(fRefNum);
  1634.         
  1635.             //****************************
  1636.             // Draw it...
  1637.             //*    let update window handle the draw
  1638.             //*    Q3ViewerDraw(info->viewer_3DMF);
  1639.         }
  1640.         
  1641.         //********************************
  1642.         // Dispose the viewer when done.
  1643.         //*    it will get disposed of when we close the window
  1644.         //    Q3ViewerDispose(viewer);
  1645.     }
  1646.     return(returnFlag);
  1647. }
  1648.  
  1649.  
  1650. //*************************************************************************
  1651. Boolean    QD3D_Process3DMFviewerEvent(TYPEwindowInfoPtr tinfo, EventRecord *eventPtr)
  1652. {
  1653. Boolean        eventHandled;
  1654. GrafPtr        savePort;
  1655.  
  1656.     eventHandled    =    false;
  1657.  
  1658.     if (tinfo->viewer_3DMF)
  1659.     {
  1660.         GetPort(&savePort);
  1661.         SetPort(tinfo->wptr);
  1662.         
  1663.         eventHandled    =    Q3ViewerEvent(tinfo->viewer_3DMF, eventPtr);
  1664.         if (eventHandled)
  1665.         {
  1666.             SysBeep(1);
  1667.         }
  1668.     
  1669.         SetPort(savePort);
  1670.     }
  1671.     return(eventHandled);
  1672. }
  1673.  
  1674.  
  1675. //*************************************************************************
  1676. void    QD3D_3DMFviewerUpdateEvent(TYPEwindowInfoPtr tinfo, EventRecord *eventPtr)
  1677. {
  1678. GrafPtr            savePort;
  1679.  
  1680.     GetPort(&savePort);
  1681.     SetPort(tinfo->wptr);
  1682.  
  1683.     EraseRect(&tinfo->wptr->portRect);
  1684.     if (tinfo->viewer_3DMF)
  1685.     {
  1686.         SetCursorWatch();
  1687.         
  1688.         Q3ViewerDraw(tinfo->viewer_3DMF);                //*  draw the viewer
  1689.         
  1690.         SetCursorArrow();
  1691.     }
  1692.     SetPort(savePort);
  1693. }
  1694.  
  1695.  
  1696.  
  1697. //*************************************************************************************
  1698. static void    Write_3DMFScene(    TYPEwindowInfoPtr    tinfo,
  1699.                                 TQ3FileObject        file,
  1700.                                 short                textMode)
  1701. {
  1702. TQ3GroupPosition    gPos;
  1703. TQ3Object            object;
  1704. TQ3ViewStatus        fileStatus;
  1705. TQ3Status            status;
  1706.  
  1707.  
  1708.     if (Q3File_OpenWrite(file, (textMode ? kQ3FileModeText : 0)) != kQ3Success)
  1709.     {
  1710.         SetCursor(&qd.arrow);
  1711.         return;
  1712.     }
  1713.     
  1714.     Q3View_StartWriting(tinfo->qd3D_view, file);
  1715. #if 0    
  1716.     if (theDocument->viewHints != nil)
  1717.     {
  1718.         if (Q3Object_Submit(theDocument->viewHints, tinfo->qd3D_view) == kQ3Failure)
  1719.         {
  1720.             Q3File_Cancel(file);
  1721.             SetCursor(&qd.arrow);
  1722.             return;
  1723.         }
  1724.     }
  1725. #endif
  1726.     fileStatus    =    kQ3ViewStatusRetraverse;
  1727.     while (fileStatus == kQ3ViewStatusRetraverse)
  1728.     {
  1729.         if (tinfo->qd3D_model != nil)
  1730.         {
  1731.             Q3Group_GetFirstPosition(tinfo->qd3D_model, &gPos);
  1732.             while (gPos)
  1733.             {
  1734.                 Q3Group_GetPositionObject(tinfo->qd3D_model, gPos, &object);
  1735.                 status    =    Q3Object_Submit(object, tinfo->qd3D_view);
  1736.                 Q3Object_Dispose(object);
  1737.                 
  1738.                 if (status != kQ3Failure)
  1739.                 {
  1740.                     Q3Group_GetNextPosition(tinfo->qd3D_model, &gPos);
  1741.                 }
  1742.             }
  1743.         }
  1744.         fileStatus    =    Q3View_EndWriting(tinfo->qd3D_view);
  1745.     }
  1746. }
  1747.  
  1748.  
  1749.  
  1750. //*************************************************************************************
  1751. Boolean SaveFile_3DMF(    TYPEwindowInfoPtr    tinfo,
  1752.                         FSSpec                *fsSpec,
  1753.                         short                fRefNum)
  1754. {
  1755. OSErr        iErr;
  1756. //long        length;
  1757. //char        *bufPtr;
  1758.  
  1759.     iErr    =    -1;
  1760.  
  1761.     if (tinfo->qd3D_model)
  1762.     {
  1763.     TQ3StorageObject    storage;
  1764.     TQ3FileObject        fd;
  1765.         
  1766.         storage    =    Q3MacintoshStorage_New(fRefNum);
  1767.         
  1768.         if (storage != nil)
  1769.         {
  1770.             fd    =    Q3File_New();
  1771.             
  1772.             if (fd != nil)
  1773.             {
  1774.                 Q3File_SetStorage(fd, storage);
  1775.                 Q3Object_Dispose(storage);
  1776.                 
  1777.                 Write_3DMFScene(tinfo,
  1778.                                 fd, 
  1779.                                 kQ3FileModeText) ;
  1780.         
  1781.                 Q3Object_Dispose(fd);
  1782.                 iErr    =    noErr;
  1783.             }
  1784.         }
  1785.     }
  1786.     return(iErr == noErr);
  1787. }
  1788.  
  1789.  
  1790.